package edu.tfh.s2.ehkbot.simulation;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.JToggleButton;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTable;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.GridBagLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.util.Vector;

import edu.tfh.s2.ehkbot.daten.InitFactory;
import edu.tfh.s2.ehkbot.daten.Protokoll;
import edu.tfh.s2.ehkbot.daten.Zeitgeber;
import edu.tfh.s2.ehkbot.daten.Protokoll.TYP;
import edu.tfh.s2.ehkbot.gerete.sensoren.Bild;
import edu.tfh.s2.ehkbot.inventar.Einkaufsauftrag;
import edu.tfh.s2.ehkbot.inventar.Einkaufsposten;
import edu.tfh.s2.ehkbot.inventar.Ware;
import edu.tfh.s2.ehkbot.inventar.Warenbestand;
import edu.tfh.s2.ehkbot.inventar.Warenbox;
import edu.tfh.s2.ehkbot.inventar.WarenboxRegal;
import edu.tfh.s2.ehkbot.steuerung.Position;
import edu.tfh.s2.ehkbot.steuerung.schnittstellen.Netzwerk;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI Builder, which is free for
 * non-commercial use. If Jigloo is being used commercially (ie, by a corporation, company or business for any
 * purpose whatever) then you should purchase a license for each developer using Jigloo. Please visit
 * www.cloudgarden.com for details. Use of Jigloo implies acceptance of these licensing terms. A COMMERCIAL
 * LICENSE HAS NOT BEEN PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR ANY
 * CORPORATE OR COMMERCIAL PURPOSE.
 */
public class SimulationGUI extends JFrame {
	/**
	 * Speichert die Information in welche Spalte sich eine Information befindet.
	 */
	private class WareboxRegalTableInfo {
		private static final int barcodeCol = 0;
		private static final int xCol = 1;
		private static final int yCol = 2;
		private static final int zCol = 3;
	}

	/**
	 * Speichert die Information in welche Spalte sich eine Information befindet.
	 */
	private class WarenbestandTableInfo {
		private static final int barcodeCol = 2;
		private static final int gewichtCol = 6;
		private static final int mengeCol = 1;
		private static final int nameCol = 0;
		private static final int xCol = 3;
		private static final int xGrosseCol = 7;
		private static final int yCol = 4;
		private static final int yGrosseCol = 8;
		private static final int zCol = 5;
		private static final int zGrosseCol = 9;
	}

	private static SimulationGUI instance = null;
	private static final long serialVersionUID = 1L;

	/**
	 * Singelton Methode (siehe Singelton Pattern)
	 * 
	 * @return Die Einzige Instanz von SimulationGUI
	 */
	public static SimulationGUI getInstance() {
		if (instance == null) {
			instance = new SimulationGUI();
		}
		return instance;
	}

	/**
	 * Liefert ob die SimulationGUI aktivert wurde
	 * 
	 * @return true fals getInstance() schon aufgerufen wurde
	 */
	public static boolean isOn() {
		return instance != null;
	}

	private JTable auftraegeTable;
	private JTextField auftraggeber;
	private JPanel auftragPanel = null;
	private JPanel geschaeftPanel = null;
	private JPanel hauptPanel = null;
	private JPanel jContentPane = null;
	private JButton jeueZeileAuftragButton;
	private JLabel jLabel1;
	private JLabel jLabel2;
	private JLabel jLabel3;
	private JLabel jLabel4;
	private JLabel jLabel5;
	private JLabel jLabel6;
	private JLabel jLabel7;
	private JLabel jLabel8;
	private JPanel jPanel1;
	private JPanel jPanel10;
	private JPanel jPanel11;
	private JPanel jPanel12;
	private JPanel jPanel13;
	private JPanel jPanel2;
	private JPanel jPanel3;
	private JPanel jPanel4;
	private JPanel jPanel7;
	private JScrollPane jScrollPane1;
	private JScrollPane jScrollPane2;
	private JScrollPane jScrollPane3;
	private JScrollPane jScrollPane4;
	private JSeparator jSeparator1;
	private JTabbedPane jTabbedPane = null;
	private JButton ladeAuftragButton;
	private JButton ladeWarenboxRegal;
	private JButton loadWarenbestandButton;
	private JTextArea logbuch;
	private JPanel logbuchPanel;
	private JButton neueZeileWarenbestandButton;
	private JButton neueZeileWarenboxRegalButton;
	private JButton refreshLogbuchButton;
	private JButton saveWarenbestandButton;
	private JButton sendeAuftragButton;
	private JCheckBox showException;
	private JCheckBox showFehler;
	private JCheckBox showInfos;
	private JCheckBox showWarnungen;
	private JButton speicherAuftragButton;
	private JButton speicherWarenboxRegalButton;
	private JSpinner verboseLevel;
	private JTable warenBestandTable;
	private JTable warenboxRegalTabel;

	private JSpinner warenboxRegalXPos;
	private JSpinner warenboxRegalYPos;
	private JSpinner warenboxRegalZPos;
	private JToggleButton ZeigeRoboterTermineljToggleButton = null;

	private JToggleButton zeigeRoutingGUIButton;

	{
		// Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
		} catch (Exception e) {
			Protokoll.getInstanc().exception(e);
		}
	}

	/**
	 * This is the default constructor
	 */
	private SimulationGUI() {
		super();
		initialize();
	}

	/**
	 * Entfern Referenzen von nicht Serialiesierbaren Objekten aus den TabeleModel.
	 * 
	 * @param tableModel
	 *            Das Table Model.
	 * @return Die Sauber version des Table Models.
	 */
	private DefaultTableModel cleanTableModel(DefaultTableModel tableModel) {
		DefaultTableModel orgModel = tableModel;
		Vector<?> clonedData = (Vector<?>) orgModel.getDataVector().clone();
		int columnCount = orgModel.getColumnCount();
		Vector<String> columnNames = new Vector<String>(columnCount);
		for (int i = 0; i < columnCount; i++) {
			columnNames.add(orgModel.getColumnName(i));
		}
		return new DefaultTableModel(clonedData, columnNames);
	}

	public JTable getAuftraegeTable() {
		if (auftraegeTable == null) {
			TableModel jTable2Model = new DefaultTableModel(new String[][] { { "", "", "" } }, new String[] {
							"Barcode", "Ware", "Anzahl" });
			auftraegeTable = new JTable();
			auftraegeTable.setModel(jTable2Model);
		}
		return auftraegeTable;
	}

	private JTextField getAuftraggeber() {
		if (auftraggeber == null) {
			auftraggeber = new JTextField();
			auftraggeber.setText("Muster Mann");
		}
		return auftraggeber;
	}

	private JPanel getAuftragPanel() {
		if (auftragPanel == null) {
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;

			auftragPanel = new JPanel();
			BoxLayout jPanel2Layout = new BoxLayout(auftragPanel, javax.swing.BoxLayout.Y_AXIS);
			auftragPanel.setLayout(jPanel2Layout);
			auftragPanel.setPreferredSize(new java.awt.Dimension(552, 364));
			auftragPanel.add(getJScrollPane3());
			auftragPanel.add(getJPanel12());
			auftragPanel.add(getJPanel11());
		}
		return auftragPanel;
	}

	/**
	 * Liefet ein Filter Objekte für JFileChooser.
	 * 
	 * @param ext
	 *            Die Extension nach der gefiltert wird.
	 * @param des
	 *            Die Beschreibung des Filters.
	 * @return Ein FileFilter.
	 */
	private FileFilter getFileFilter(final String ext, final String des) {
		return new FileFilter() {
			public boolean accept(File f) {
				return f.isDirectory() || getFileExtension(f).compareToIgnoreCase(ext) == 0;
			}

			public String getDescription() {
				return des;
			}

			public String getFileExtension(File f) {
				int pos = f.getName().lastIndexOf('.');
				if (0 < pos && pos <= f.getName().length() - 2) {
					return f.getName().substring(pos + 1);
				}
				return "";
			}
		};
	}

	private JPanel getGeschaeftPanel() {
		if (geschaeftPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.gridx = 0;
			geschaeftPanel = new JPanel();
			BoxLayout jPanel1Layout = new BoxLayout(geschaeftPanel, javax.swing.BoxLayout.Y_AXIS);
			geschaeftPanel.setLayout(jPanel1Layout);
			geschaeftPanel.add(getJPanel2());
			geschaeftPanel.add(getJScrollPane1());
			geschaeftPanel.add(getJPanel10());
			geschaeftPanel.add(getJSeparator1());
			geschaeftPanel.add(getJPanel1());
			geschaeftPanel.add(getJScrollPane2());
			geschaeftPanel.add(getJPanel13());
			geschaeftPanel.add(getJPanel7());

		}
		return geschaeftPanel;
	}

	private JPanel getHauptPanel() {
		if (hauptPanel == null) {
			hauptPanel = new JPanel();
			hauptPanel.setLayout(null);
			hauptPanel.add(getZeigeRoboterTermineljToggleButton(), null);
			hauptPanel.add(getZeigeRoutingGUIButton());
		}
		return hauptPanel;
	}

	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(1);
			jContentPane = new JPanel();
			jContentPane.setLayout(gridLayout);
			jContentPane.add(getJTabbedPane(), null);
		}
		return jContentPane;
	}

	private JLabel getJLabel1() {
		if (jLabel1 == null) {
			jLabel1 = new JLabel();
			jLabel1.setText("Auftragber");
		}
		return jLabel1;
	}

	private JLabel getJLabel2() {
		if (jLabel2 == null) {
			jLabel2 = new JLabel();
			jLabel2.setText("Verbose Level");
		}
		return jLabel2;
	}

	private JLabel getJLabel3() {
		if (jLabel3 == null) {
			jLabel3 = new JLabel();
			jLabel3.setText("WarenboxRegal Position");
		}
		return jLabel3;
	}

	private JLabel getJLabel4() {
		if (jLabel4 == null) {
			jLabel4 = new JLabel();
			jLabel4.setText("x");
		}
		return jLabel4;
	}

	private JLabel getJLabel5() {
		if (jLabel5 == null) {
			jLabel5 = new JLabel();
			jLabel5.setText("y");
		}
		return jLabel5;
	}

	private JLabel getJLabel6() {
		if (jLabel6 == null) {
			jLabel6 = new JLabel();
			jLabel6.setText("z");
		}
		return jLabel6;
	}

	private JLabel getJLabel7() {
		if (jLabel7 == null) {
			jLabel7 = new JLabel();
			jLabel7.setText("Waren");
		}
		return jLabel7;
	}

	private JLabel getJLabel8() {
		if (jLabel8 == null) {
			jLabel8 = new JLabel();
			jLabel8.setText("Warenboxen FÃ¤cher");
		}
		return jLabel8;
	}

	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			jPanel1 = new JPanel();
			jPanel1.setPreferredSize(new java.awt.Dimension(114, 15));
			jPanel1.add(getJLabel8());
		}
		return jPanel1;
	}

	private JPanel getJPanel10() {
		if (jPanel10 == null) {
			jPanel10 = new JPanel();
			FlowLayout jPanel10Layout = new FlowLayout();
			jPanel10.setLayout(jPanel10Layout);
			jPanel10.add(getNeueZeileWarenbestandButton());
			jPanel10.add(getLoadWarenbestandButton());
			jPanel10.add(getSaveWarenbestandButton());
		}
		return jPanel10;
	}

	private JPanel getJPanel11() {
		if (jPanel11 == null) {
			jPanel11 = new JPanel();
			FlowLayout jPanel11Layout = new FlowLayout();
			jPanel11.setLayout(jPanel11Layout);
			jPanel11.add(getNeueZeileAuftragButton());
			jPanel11.add(getLadeAuftragButton());
			jPanel11.add(getSpeicherAuftragButton());
			jPanel11.add(getSendeAuftragButton());
		}
		return jPanel11;
	}

	private JPanel getJPanel12() {
		if (jPanel12 == null) {
			jPanel12 = new JPanel();
			GridBagLayout jPanel12Layout = new GridBagLayout();
			jPanel12.setLayout(jPanel12Layout);
			jPanel12.add(getJLabel1(), new GridBagConstraints(
				0,
				0,
				1,
				1,
				0.0,
				0.0,
				GridBagConstraints.CENTER,
				GridBagConstraints.NONE,
				new Insets(0, 0, 0, 0),
				0,
				0));
			jPanel12.add(getAuftraggeber(), new GridBagConstraints(
				1,
				0,
				1,
				1,
				0.0,
				0.0,
				GridBagConstraints.CENTER,
				GridBagConstraints.HORIZONTAL,
				new Insets(0, 0, 0, 0),
				0,
				0));
			jPanel12Layout.rowWeights = new double[] { 0.1, 0.1, 0.1, 0.1 };
			jPanel12Layout.rowHeights = new int[] { 7, 7, 7, 7 };
			jPanel12Layout.columnWeights = new double[] { 0.1, 0.1 };
			jPanel12Layout.columnWidths = new int[] { 7, 7 };
		}
		return jPanel12;
	}

	private JPanel getJPanel13() {
		if (jPanel13 == null) {
			jPanel13 = new JPanel();
			FlowLayout jPanel13Layout = new FlowLayout();
			jPanel13.setLayout(jPanel13Layout);
			jPanel13.add(getJLabel3());
			jPanel13.add(getWarenboxRegalXPos());
			jPanel13.add(getJLabel4());
			jPanel13.add(getWarenboxRegalYPos());
			jPanel13.add(getJLabel5());
			jPanel13.add(getWarenboxRegalZPos());
			jPanel13.add(getJLabel6());
		}
		return jPanel13;
	}

	private JPanel getJPanel2() {
		if (jPanel2 == null) {
			jPanel2 = new JPanel();
			jPanel2.setPreferredSize(new java.awt.Dimension(36, 15));
			jPanel2.add(getJLabel7());
		}
		return jPanel2;
	}

	private JPanel getJPanel3() {
		if (jPanel3 == null) {
			jPanel3 = new JPanel();
			jPanel3.add(getRefreshLogbuchButton());
			jPanel3.add(getJLabel2());
			jPanel3.add(getVerboseLevel());
			jPanel3.add(getJPanel4());
		}
		return jPanel3;
	}

	private JPanel getJPanel4() {
		if (jPanel4 == null) {
			jPanel4 = new JPanel();
			jPanel4.setBorder(BorderFactory.createTitledBorder("Typ"));
			jPanel4.add(getShowInfos());
			jPanel4.add(getShowWarnungen());
			jPanel4.add(getShowFehler());
			jPanel4.add(getShowException());
		}
		return jPanel4;
	}

	private JPanel getJPanel7() {
		if (jPanel7 == null) {
			jPanel7 = new JPanel();
			FlowLayout jPanel7Layout = new FlowLayout();
			jPanel7.setLayout(jPanel7Layout);
			jPanel7.add(getNeueZeileWarenboxRegalButton());
			jPanel7.add(getLadeWarenboxRegalButton());
			jPanel7.add(getSpeicherWarenboxRegalButton());
		}
		return jPanel7;
	}

	private JScrollPane getJScrollPane1() {
		if (jScrollPane1 == null) {
			jScrollPane1 = new JScrollPane();
			jScrollPane1.setViewportView(getWarenBestandTable());
		}
		return jScrollPane1;
	}

	private JScrollPane getJScrollPane2() {
		if (jScrollPane2 == null) {
			jScrollPane2 = new JScrollPane();
			jScrollPane2.setViewportView(getWarenboxRegalTabel());
		}
		return jScrollPane2;
	}

	private JScrollPane getJScrollPane3() {
		if (jScrollPane3 == null) {
			jScrollPane3 = new JScrollPane();
			jScrollPane3.setBounds(220, 122, 415, 258);
			jScrollPane3.setPreferredSize(new java.awt.Dimension(826, 315));
			jScrollPane3.setViewportView(getAuftraegeTable());
		}
		return jScrollPane3;
	}

	private JScrollPane getJScrollPane4() {
		if (jScrollPane4 == null) {
			jScrollPane4 = new JScrollPane();
			jScrollPane4.setPreferredSize(new java.awt.Dimension(826, 416));
			jScrollPane4.setViewportView(getLogbuch());
		}
		return jScrollPane4;
	}

	private JSeparator getJSeparator1() {
		if (jSeparator1 == null) {
			jSeparator1 = new JSeparator();
		}
		return jSeparator1;
	}

	private JTabbedPane getJTabbedPane() {
		if (jTabbedPane == null) {
			jTabbedPane = new JTabbedPane();
			jTabbedPane.setEnabled(true);
			jTabbedPane.addTab("Hauptbildschirm", null, getHauptPanel(), null);
			jTabbedPane.addTab("Geschäft", null, getGeschaeftPanel(), null);
			jTabbedPane.addTab("Aufträge", null, getAuftragPanel(), null);
			jTabbedPane.addTab("Logbuch", null, getLogbuchPanel(), null);

		}
		return jTabbedPane;
	}

	private JButton getLadeAuftragButton() {
		if (ladeAuftragButton == null) {
			ladeAuftragButton = new JButton();
			ladeAuftragButton.setText("Lade Auftrag");
			ladeAuftragButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					try {
						loadTableDialog(auftraegeTable, "auftrag", "EHK Auftrags Datei *.auftrag");
					} catch (IOException e) {
						Protokoll.getInstanc().exception(e);
					} catch (ClassNotFoundException e) {
						Protokoll.getInstanc().exception(e);
					}
				}
			});
		}
		return ladeAuftragButton;
	}

	private JButton getLadeWarenboxRegalButton() {
		if (ladeWarenboxRegal == null) {
			ladeWarenboxRegal = new JButton();
			ladeWarenboxRegal.setText("Lade Warenbox Regal");
			ladeWarenboxRegal.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					try {
						loadTableDialog(
							warenboxRegalTabel,
							"warenboxfaecher",
							"EHKBot Warenboxfaecher *.warenboxfaecher");
					} catch (IOException e) {
						Protokoll.getInstanc().exception(e);
					} catch (ClassNotFoundException e) {
						Protokoll.getInstanc().exception(e);
					}
				}
			});
		}
		return ladeWarenboxRegal;
	}

	private JButton getLoadWarenbestandButton() {
		if (loadWarenbestandButton == null) {
			loadWarenbestandButton = new JButton();
			loadWarenbestandButton.setText("Lade Warenbestand");
			loadWarenbestandButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					try {
						loadTableDialog(
							warenBestandTable,
							"warenbestand",
							"Warenbestands Datei *.warenbestand");
					} catch (IOException e) {
						Protokoll.getInstanc().exception(e);
					} catch (ClassNotFoundException e) {
						Protokoll.getInstanc().exception(e);
					}
				}
			});
		}
		return loadWarenbestandButton;
	}

	private JTextArea getLogbuch() {
		if (logbuch == null) {
			logbuch = new JTextArea();
		}
		return logbuch;
	}

	private JPanel getLogbuchPanel() {
		if (logbuchPanel == null) {
			logbuchPanel = new JPanel();
			BoxLayout jPanel5Layout = new BoxLayout(logbuchPanel, javax.swing.BoxLayout.Y_AXIS);
			logbuchPanel.setLayout(jPanel5Layout);
			logbuchPanel.add(getJScrollPane4());
			logbuchPanel.add(getJPanel3());
		}
		return logbuchPanel;
	}

	private JButton getNeueZeileAuftragButton() {
		if (jeueZeileAuftragButton == null) {
			jeueZeileAuftragButton = new JButton();
			jeueZeileAuftragButton.setText("Neue Zeile");
			jeueZeileAuftragButton.addActionListener(new ActionListener() {
				@SuppressWarnings("unchecked")
				public void actionPerformed(ActionEvent evt) {
					/*
					 * Fügt eine neue Zeile in die Tabelle ein.
					 */
					DefaultTableModel model = (DefaultTableModel) auftraegeTable.getModel();
					model.addRow(new Vector());
				}
			});
		}
		return jeueZeileAuftragButton;
	}

	private JButton getNeueZeileWarenbestandButton() {
		if (neueZeileWarenbestandButton == null) {
			neueZeileWarenbestandButton = new JButton();
			neueZeileWarenbestandButton.setText("Neue Zeile");
			neueZeileWarenbestandButton.addActionListener(new ActionListener() {
				@SuppressWarnings("unchecked")
				public void actionPerformed(ActionEvent evt) {
					DefaultTableModel model = (DefaultTableModel) warenBestandTable.getModel();
					model.addRow(new Vector());
				}
			});
		}
		return neueZeileWarenbestandButton;
	}

	private JButton getNeueZeileWarenboxRegalButton() {
		if (neueZeileWarenboxRegalButton == null) {
			neueZeileWarenboxRegalButton = new JButton();
			neueZeileWarenboxRegalButton.setText("Neue Zeile");
			neueZeileWarenboxRegalButton.addActionListener(new ActionListener() {
				@SuppressWarnings("unchecked")
				public void actionPerformed(ActionEvent evt) {
					DefaultTableModel model = (DefaultTableModel) warenboxRegalTabel.getModel();
					model.addRow(new Vector());
				}
			});
		}
		return neueZeileWarenboxRegalButton;
	}

	private JButton getRefreshLogbuchButton() {
		if (refreshLogbuchButton == null) {
			refreshLogbuchButton = new JButton();
			refreshLogbuchButton.setText("Refresh Logbuch");
			refreshLogbuchButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					/*
					 * Hollt sich die Informationen aus den Protokoll und zeigt sie an.
					 */
					int verbose = (Integer) verboseLevel.getValue();
					boolean showInfos = getShowInfos().isSelected();
					boolean showFehler = getShowFehler().isSelected();
					boolean showWarnungen = getShowWarnungen().isSelected();
					boolean showExceptions = getShowException().isSelected();
					Vector<Protokoll.TYP> tmp = new Vector<Protokoll.TYP>();
					if (showInfos)
						tmp.add(Protokoll.TYP.INFO);
					if (showFehler)
						tmp.add(Protokoll.TYP.FEHLER);
					if (showWarnungen)
						tmp.add(Protokoll.TYP.WARNUNG);
					if (showExceptions)
						tmp.add(Protokoll.TYP.EXCEPTION);
					getLogbuch().setText(
						Protokoll.getInstanc().getProtokoll(verbose, tmp.toArray(new TYP[0])));
				}
			});
		}
		return refreshLogbuchButton;
	}

	private JButton getSaveWarenbestandButton() {
		if (saveWarenbestandButton == null) {
			saveWarenbestandButton = new JButton();
			saveWarenbestandButton.setText("Speicher Warenbestand");
			saveWarenbestandButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					saveTableDialog(
						"warenbestand",
						"EHKBot Warenbestand *.warenbestand",
						cleanTableModel((DefaultTableModel) warenBestandTable.getModel()));
				}
			});
		}
		return saveWarenbestandButton;
	}

	public JButton getSendeAuftragButton() {
		if (sendeAuftragButton == null) {
			sendeAuftragButton = new JButton();
			sendeAuftragButton.setText("Sende Auftrag an EHKBot");
			sendeAuftragButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					/*
					 * Baut aus der Table einen Auftrag der über das Netzwerk gesendet wird.
					 */
					Warenbestand db = InitFactory.getInstance().getWarenbestand();
					DefaultTableModel df = cleanTableModel((DefaultTableModel) auftraegeTable.getModel());
					Einkaufsauftrag ek = new Einkaufsauftrag(
						auftraggeber.getText(),
						Zeitgeber.getInstance().getCurrentDate());

					/*
					 * Packt die Waren ein
					 */
					Vector<?> clonedData = (Vector<?>) df.getDataVector().clone();
					for (int k = 0; k < clonedData.size(); ++k) {
						try {
							Vector<String> row = (Vector<String>) clonedData.get(k);
							int barcode = Integer.valueOf(row.get(0)).intValue();
							int menge = Integer.valueOf(row.get(2)).intValue();

							Ware w = db.findeWare(barcode);

							ek.addEinkausposten(new Einkaufsposten(w, menge));
						} catch (NumberFormatException e) {
							Protokoll.getInstanc().exception(e);
						}
					}

					/*
					 * Serialiesiert sie und versendet sie als Bytestream über das Netzwerk.
					 */
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					ObjectOutputStream oos = null;
					try {
						oos = new ObjectOutputStream(out);
						oos.writeObject(ek);
						oos.close();
					} catch (IOException e) {
						Protokoll.getInstanc().exception(e);
					}

					Netzwerk.getInstance().sendeNachricht(out.toByteArray(), "AuftragsQuelle");
				}
			});
		}
		return sendeAuftragButton;
	}

	private JCheckBox getShowException() {
		if (showException == null) {
			showException = new JCheckBox();
			showException.setText("Exception");
			showException.setSelected(true);
		}
		return showException;
	}

	private JCheckBox getShowFehler() {
		if (showFehler == null) {
			showFehler = new JCheckBox();
			showFehler.setText("Fehler");
			showFehler.setSelected(true);
		}
		return showFehler;
	}

	private JCheckBox getShowInfos() {
		if (showInfos == null) {
			showInfos = new JCheckBox();
			showInfos.setText("Infos");
			showInfos.setSelected(true);
		}
		return showInfos;
	}

	private JCheckBox getShowWarnungen() {
		if (showWarnungen == null) {
			showWarnungen = new JCheckBox();
			showWarnungen.setText("Wanungen");
			showWarnungen.setSelected(true);
		}
		return showWarnungen;
	}

	private JButton getSpeicherAuftragButton() {
		if (speicherAuftragButton == null) {
			speicherAuftragButton = new JButton();
			speicherAuftragButton.setText("Speicher Auftrag");
			speicherAuftragButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					saveTableDialog(
						"auftrag",
						"EHKBot auftrag *.auftrag",
						cleanTableModel((DefaultTableModel) auftraegeTable.getModel()));
				}
			});
		}
		return speicherAuftragButton;
	}

	private JButton getSpeicherWarenboxRegalButton() {
		if (speicherWarenboxRegalButton == null) {
			speicherWarenboxRegalButton = new JButton();
			speicherWarenboxRegalButton.setText("Speicher Warenbox Regal");
			speicherWarenboxRegalButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					saveTableDialog(
						"warenboxfaecher",
						"EHKBot Warenboxfaecher *.warenboxfaecher",
						cleanTableModel((DefaultTableModel) warenboxRegalTabel.getModel()));
				}
			});

		}
		return speicherWarenboxRegalButton;
	}

	private JSpinner getVerboseLevel() {
		if (verboseLevel == null) {

			Integer value = new Integer(3);
			Integer min = new Integer(0);
			Integer max = new Integer(100);
			Integer step = new Integer(1);
			SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, step);

			verboseLevel = new JSpinner();
			verboseLevel.setModel(model);
		}
		return verboseLevel;
	}

	/**
	 * Baut aus den Daten aus den JTable warenbestandTable den Warenbestand auf.
	 * 
	 * @return Den Warenbestand.
	 */
	@SuppressWarnings("unchecked")
	public Warenbestand getWarenbestand() {
		JTable warenbestandTable = getWarenBestandTable();

		Warenbestand wb = new Warenbestand();

		DefaultTableModel orgModel = (DefaultTableModel) warenbestandTable.getModel();
		Vector<?> clonedData = (Vector<?>) orgModel.getDataVector().clone();
		for (int k = 0; k < clonedData.size(); ++k) {
			try {
				Vector<String> row = (Vector<String>) clonedData.get(k);
				String name = row.get(WarenbestandTableInfo.nameCol);
				int menge = Integer.valueOf(row.get(WarenbestandTableInfo.mengeCol)).intValue();
				int[] groesse = new int[3];
				groesse[0] = Integer.valueOf(row.get(WarenbestandTableInfo.xGrosseCol)).intValue();
				groesse[1] = Integer.valueOf(row.get(WarenbestandTableInfo.yGrosseCol)).intValue();
				groesse[2] = Integer.valueOf(row.get(WarenbestandTableInfo.zGrosseCol)).intValue();
				int gewicht = Integer.valueOf(row.get(WarenbestandTableInfo.gewichtCol)).intValue();
				int barcode = Integer.valueOf(row.get(WarenbestandTableInfo.barcodeCol)).intValue();
				int xpos = Integer.valueOf(row.get(WarenbestandTableInfo.xCol)).intValue();
				int ypos = Integer.valueOf(row.get(WarenbestandTableInfo.yCol)).intValue();
				int zpos = Integer.valueOf(row.get(WarenbestandTableInfo.zCol)).intValue();

				Ware.Beschafenheit[] beschafenheit = new Ware.Beschafenheit[] { Ware.Beschafenheit.UNBEKANNT };

				Ware w = new Ware(name, gewicht, groesse, barcode, beschafenheit, new Bild(null));
				w.setPosition(xpos, ypos, zpos);
				wb.add(w, menge);
			} catch (NumberFormatException e) {
				Protokoll.getInstanc().exception(e);
			}

		}
		return wb;
	}

	public JTable getWarenBestandTable() {
		if (warenBestandTable == null) {
			warenBestandTable = new JTable();
			warenBestandTable.setLayout(null);

			warenBestandTable.setModel(new DefaultTableModel(new String[][] { { "", "", "", "", "", "", "",
							"", "", "" } }, new String[] { "Name", "Menge", "Barcode", "x[mm]", "y[mm]",
							"z[mm]", "Gewicht[g]", "x ausd.[mm]", "y ausd.[mm]", "z ausd.[mm]" }));
		}
		return warenBestandTable;
	}

	/**
	 * Baut aus den Daten aus den JTable warenboxTable das WarenboxRegal.
	 * 
	 * @return Das WarenboxRegal.
	 */
	@SuppressWarnings("unchecked")
	public WarenboxRegal getWarenboxregal() {
		JTable warenboxTable = getWarenboxRegalTabel();

		DefaultTableModel orgModel = (DefaultTableModel) warenboxTable.getModel();
		Vector<?> clonedData = (Vector<?>) orgModel.getDataVector().clone();

		WarenboxRegal wbr = new WarenboxRegal(clonedData.size(), getWarenboxRegalPosition());
		for (int k = 0; k < clonedData.size(); ++k) {
			try {
				Vector<String> row = (Vector<String>) clonedData.get(k);
				int barcode = Integer.valueOf(row.get(WareboxRegalTableInfo.barcodeCol)).intValue();
				int xpos = Integer.valueOf(row.get(WareboxRegalTableInfo.xCol)).intValue();
				int ypos = Integer.valueOf(row.get(WareboxRegalTableInfo.yCol)).intValue();
				int zpos = Integer.valueOf(row.get(WareboxRegalTableInfo.zCol)).intValue();
				Warenbox wb = new Warenbox(barcode);
				wbr.putWarenbox(k, wb, new Position(xpos, ypos, zpos));
			} catch (NumberFormatException e) {
				Protokoll.getInstanc().exception(e);
			}

		}

		return wbr;
	}

	public Position getWarenboxRegalPosition() {
		int x = (Integer) this.getWarenboxRegalXPos().getValue();
		int y = (Integer) this.getWarenboxRegalYPos().getValue();
		int z = (Integer) this.getWarenboxRegalZPos().getValue();
		Position p = new Position(x, y, z);
		return p;
	}

	public JTable getWarenboxRegalTabel() {
		if (warenboxRegalTabel == null) {
			TableModel WarenboxRegalTabelModel = new DefaultTableModel(
				new String[][] { { "", "", "", "" } },
				new String[] { "Barcode", "x", "y", "z" });
			warenboxRegalTabel = new JTable();
			warenboxRegalTabel.setModel(WarenboxRegalTabelModel);
		}
		return warenboxRegalTabel;
	}

	private JSpinner getWarenboxRegalXPos() {
		if (warenboxRegalXPos == null) {
			Integer value = new Integer(1);
			Integer min = new Integer(0);
			Integer max = new Integer(10000000);
			Integer step = new Integer(1);
			SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, step);
			warenboxRegalXPos = new JSpinner();
			warenboxRegalXPos.setModel(model);
			getWarenboxRegalXPos().getEditor().setSize(30, 18);
			warenboxRegalXPos.setSize(30, 22);
		}
		return warenboxRegalXPos;
	}

	private JSpinner getWarenboxRegalYPos() {
		if (warenboxRegalYPos == null) {
			Integer value = new Integer(1);
			Integer min = new Integer(0);
			Integer max = new Integer(10000000);
			Integer step = new Integer(1);
			SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, step);
			warenboxRegalYPos = new JSpinner();
			warenboxRegalYPos.setModel(model);
		}
		return warenboxRegalYPos;
	}

	private JSpinner getWarenboxRegalZPos() {
		if (warenboxRegalZPos == null) {
			Integer value = new Integer(1);
			Integer min = new Integer(0);
			Integer max = new Integer(10000000);
			Integer step = new Integer(1);
			SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, step);
			warenboxRegalZPos = new JSpinner();
			warenboxRegalZPos.setModel(model);
		}
		return warenboxRegalZPos;
	}

	public JToggleButton getZeigeRoboterTermineljToggleButton() {
		if (ZeigeRoboterTermineljToggleButton == null) {
			ZeigeRoboterTermineljToggleButton = new JToggleButton();
			ZeigeRoboterTermineljToggleButton.setBounds(new Rectangle(15, 15, 166, 31));
			ZeigeRoboterTermineljToggleButton.setText("Zeige Roboter TerminalGUI");
			ZeigeRoboterTermineljToggleButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					AbstractButton abstractButton = (AbstractButton) e.getSource();
					boolean selected = abstractButton.getModel().isSelected();
					TerminalGUI.getInstance().setVisible(selected);
				}
			});
		}
		return ZeigeRoboterTermineljToggleButton;
	}

	public JToggleButton getZeigeRoutingGUIButton() {
		if (zeigeRoutingGUIButton == null) {
			zeigeRoutingGUIButton = new JToggleButton();
			zeigeRoutingGUIButton.setText("Zeige RoutingGUI");
			zeigeRoutingGUIButton.setBounds(15, 65, 166, 31);
			zeigeRoutingGUIButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent evt) {
					AbstractButton abstractButton = (AbstractButton) evt.getSource();
					boolean selected = abstractButton.getModel().isSelected();
					RoutingGUI.getInstance().setVisible(selected);
					RoutingGUI.getInstance().refreshMapPanel();
				}
			});
		}
		return zeigeRoutingGUIButton;
	}

	private void initialize() {
		this.setSize(841, 538);
		this.setContentPane(getJContentPane());
		this.setTitle("EHKBot SimulationGUI");
		this.setPreferredSize(new java.awt.Dimension(841, 538));
	}

	/**
	 * Öffnet ein File Dialog und läd dann ein JTable aus einer Datei.
	 * 
	 * @param jtable
	 *            In das JTable werden die Daten geladen.
	 * @param ext
	 *            Die Extension für den Filter in FileDialog.
	 * @param des
	 *            Die Beschreibung des Filters in FileDialog.
	 * @throws IOException
	 *             Wenn die Datei nicht gelesen worden konnte.
	 * @throws ClassNotFoundException
	 *             Wenn in der Datei kein JTable abgelt ist.
	 */
	private void loadTableDialog(JTable jtable, String ext, String des) throws IOException,
		ClassNotFoundException {
		JFileChooser jf = new JFileChooser();
		jf.setFileFilter(getFileFilter(ext, des));
		int retval = jf.showOpenDialog(null);
		if (retval == JFileChooser.APPROVE_OPTION) {
			File f = jf.getSelectedFile();
			loadTablesFromFile(jtable, f);
		}

	}

	/**
	 * Läd dann ein JTable aus einer Datei.
	 * 
	 * @param jtable
	 *            In das JTable werden die Daten geladen.
	 * @param file
	 *            Die Datei aus der geladen wird.
	 * @throws IOException
	 *             Wenn die Datei nicht gelesen worden konnte.
	 * @throws ClassNotFoundException
	 *             Wenn in der Datei kein JTable abgelt ist.
	 */
	public void loadTablesFromFile(JTable jt, File file) throws IOException, ClassNotFoundException {
		FileInputStream fileIn = new FileInputStream(file);
		ObjectInputStream input = new ObjectInputStream(fileIn);
		Object ob = input.readObject();
		if (ob != null)
			jt.setModel((TableModel) ob);
	}

	/**
	 * Öffnet ein File Dialog und speicher dann das ob in eine Datei.
	 * 
	 * @param ext
	 *            Die Extension für den Filter in FileDialog.
	 * @param des
	 *            Die Beschreibung des Filters in FileDialog.
	 * @param ob
	 *            Das Objekt welches gespeichert werden soll.ist.
	 */
	private void saveTableDialog(String ext, String des, Object ob) {
		JFileChooser jf = new JFileChooser();
		jf.setFileFilter(getFileFilter(ext, des));
		int retval = jf.showSaveDialog(null);
		if (retval == JFileChooser.APPROVE_OPTION) {
			try {
				File f = jf.getSelectedFile();
				int pos = f.getName().lastIndexOf("." + ext);
				if (pos != (f.getName().length() - (ext.length() + 1))) {
					f = new File(f.getAbsoluteFile() + "." + ext);
				}
				FileOutputStream fileOut = new FileOutputStream(f);
				ObjectOutputStream output = new ObjectOutputStream(fileOut);
				output.writeObject(ob);
			} catch (IOException e) {
				Protokoll.getInstanc().exception(e);
			}
		}
	}
}
